5 kyu
將字串結尾的數字部分遞增,若不是數字則加上一個 1。
並且維持數字的字元數量,例如:012 → 013。
使用正則表達式,將字串拆成兩段;
前面可能有字串或數字,但結尾必須只有數字。
捕獲數字的部分,如果字尾獲取不到,就直接+1。
利用字串長度,確保遞增後的數字長度與原本相同。
let reg = /^(...)(...)$/
let result = str.match(reg)
if(!result) return str + "1"
return result[1] + (result[2]+1)
function incrementString(strng) {
let regExp = /^(.*?)(\d+)$/;
let result = strng.match(regExp);
if (!result) return strng + "1";
let number = +result[2] + 1;
return result[1] + "0".repeat(Math.max(result[2].length - String(number).length, 0)) + number;
}
使用 () 可個別捕獲不同的正則條件,match 利用匹配的結果建立陣列。
/^(.*?)(\d+)$/
(.*?)表示匹配任意數量的字元,但以後面的捕獲分組為主。
. 表示單一字元;* 表示零到多次;? 表示零或一,在這裡為表示匹配較少。foobar00999 為例,若第一捕獲有 ? 限制:["foobar00999", "foobar", "00999"]。? 限制:["foobar00999", "foobar0099", "9"]。(\d+)表示匹配一到多次的數字。match 返回的結果,將數字的部分 +1。
原始匹配的長度、扣掉轉換成數字並遞增後的長度,Math.max 與 0 取最大值(因為可能有負數),得到 repeat 計算需要補的 0 的次數;最後跟第一捕獲組拼接出結果。
let incrementString = str => str.replace(/([0-8]|\d?9+)?$/, (e) => e ? + e + 1 : 1)
直接使用 replace 方法,會返回處理後的字串。
正則表達式可多次拆分來看:
(…)?$ 表示符合 () 捕獲條件零或一次,$ 表示這個捕獲在字串結尾。
裡面的條件 [0-8]|\d?9+ 可能有兩種情況;結尾數字由 0-8 組成,或者最後位為 9,一次或多次的 9,且前面拼接一個或零個數字 0-9。
這個做法用意是分為要進位,以及不用進位兩種狀況;如果不需進位就獲取最後尾一個數字。
如果需要進位,則獲取字尾數來的連續的 9,以及它前面的數字。
符合條件一:foobar000,只捕獲最後一個 0。
符合條件二:foobar00999,捕獲 0999。
第二參數的三元運算子,如果符合條件則將 match 的內容轉為數字後+1,若不符合條件則表示沒有數字做為結尾,則返回 1。
如果要問我自學過程中,理解哪些知識點時最讓我煎熬?
我第一個想到遞迴、第二大概就是正則表達式。
(不過自從學了 Functional Programming,又再加上 Functional Programming🫠)
不過,越是解題就越是感受到正則的強大,
搭配一些簡單的方法就能辦到很多事、解決很多問題。
有機會一定要找一下訓練寫正則條件的平台‼️